package com.pt.security;

import com.pt.entity.User;
import com.pt.service.UserService;
import io.jsonwebtoken.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Component
public class JwtTokenProvider {

    private final UserService userService;

    @Value("${jwt.secret}")
    private String jwtSecret;

    @Value("${jwt.expiration}")
    private int jwtExpirationInSec;

    @Value("${jwt.expiration.ms}")
    private long jwtExpirationInMs;

    public JwtTokenProvider(@Lazy UserService userService) {
        this.userService = userService;
    }

    public String generateToken(Authentication authentication) {
        UserDetails userDetails;
        if (authentication.getPrincipal() instanceof UserDetails) {
            userDetails = (UserDetails) authentication.getPrincipal();
        } else if (authentication.getPrincipal() instanceof UserPrincipal) {
            userDetails = (UserPrincipal) authentication.getPrincipal();
        } else {
            throw new IllegalArgumentException("Authentication principal must be UserDetails or UserPrincipal");
        }
        
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + jwtExpirationInSec * 1000L);
        
        String subject = userDetails instanceof UserPrincipal ? 
                Long.toString(((UserPrincipal) userDetails).getId()) : 
                userDetails.getUsername();

        return Jwts.builder()
                .setSubject(subject)
                .claim("authorities", authentication.getAuthorities().stream()
                        .map(GrantedAuthority::getAuthority)
                        .collect(Collectors.joining(",")))
                .setIssuedAt(new Date())
                .setExpiration(expiryDate)
                .signWith(SignatureAlgorithm.HS512, jwtSecret)
                .compact();
    }

    public String generateToken(Long userId) {
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + jwtExpirationInMs);

        return Jwts.builder()
                .setSubject(String.valueOf(userId))
                .setIssuedAt(new Date())
                .setExpiration(expiryDate)
                .signWith(SignatureAlgorithm.HS512, jwtSecret)
                .compact();
    }

    public Authentication getAuthentication(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(jwtSecret)
                .parseClaimsJws(token)
                .getBody();

        List<GrantedAuthority> authorities = new ArrayList<>();
        // 添加默认的ROLE_USER权限
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        
        try {
            Long userId = Long.parseLong(claims.getSubject());
            // 重新查询用户信息以获取最新状态
            User user = userService.getUserById(userId);
            if (user == null) {
                log.warn("用户不存在: {}", userId);
                return null;
            }
            
            // 检查用户状态，如果被禁用则返回null (状态码0表示禁用)
            if (user.getStatus() == 0) {
                log.warn("用户已被禁用: {}", userId);
                return null;
            }
            
            // 如果是管理员用户，添加ROLE_ADMIN权限
            if (user.isAdmin()) {
                authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
                log.info("用户 {} 是管理员", userId);
            }
            
            UserPrincipal principal = new UserPrincipal(userId, user.getUsername(), user.getPassword(), 
                                        user.getEmail(), user.getStatus(), authorities);
            
            return new UsernamePasswordAuthenticationToken(principal, token, authorities);
        } catch (NumberFormatException e) {
            log.warn("无效的token subject: {}", claims.getSubject());
            return null;
        }
    }

    public boolean validateToken(String authToken) {
        try {
            Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
            return true;
        } catch (SignatureException ex) {
            log.error("无效的JWT签名");
        } catch (MalformedJwtException ex) {
            log.error("无效的JWT令牌");
        } catch (ExpiredJwtException ex) {
            log.error("JWT令牌已过期");
        } catch (UnsupportedJwtException ex) {
            log.error("不支持的JWT令牌");
        } catch (IllegalArgumentException ex) {
            log.error("JWT令牌为空");
        }
        return false;
    }
} 